package com.haixee.parkdemo.gateway.utils;

import com.haixee.parkdemo.common.response.ResResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;

/**
 * @author windtreeland
 * 2021/5/10 16:57
 */
public class RequestUtil {

    public static String getIp(ServerHttpRequest request) {

        HttpHeaders httpHeaders = request.getHeaders();
        List<String> ipList = httpHeaders.get("X-Forwarded-For");

        String ip = getFirstItem(ipList);
        if (ipList != null) {
            ip = ip.split(",")[0];
        }

        if (StringUtils.isBlank(ip)) {
            ip = getFirstItem(httpHeaders.get("X-Real-Ip"));
        }

        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = getFirstItem(httpHeaders.get("Proxy-Client-IP"));
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = getFirstItem(httpHeaders.get("WL-Proxy-Client-IP"));
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = getFirstItem(httpHeaders.get("HTTP_CLIENT_IP"));
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = getFirstItem(httpHeaders.get("HTTP_X_FORWARDED_FOR"));
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            InetSocketAddress inetSocketAddress = request.getRemoteAddress();
            if (inetSocketAddress != null) {
                ip = inetSocketAddress.getHostName();
                if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
                    return ip;
                }
            }
        }
        return ip;
    }

    public static String getValueFromHeader(HttpHeaders headers, String key) {
        List<String> keyList = headers.get(key);

        if (keyList == null) {
            return null;
        }

        return StringUtils.stripToNull(keyList.get(0));
    }

    private static String getFirstItem(List<String> ipList) {
        if (ipList == null || StringUtils.isBlank(ipList.get(0))) {
            return null;
        }
        return StringUtils.trim(ipList.get(0));
    }

    public static Mono<Void> writeResponse(ServerHttpResponse response, HttpStatus status, ResResult res) {

        response.setStatusCode(status);
        String resultStr = String.format("{\"code\":%d,\"msg\":\"%s\"}", res.getCode(), res.getMsg());
        DataBuffer buffer = response.bufferFactory().wrap(resultStr.getBytes(StandardCharsets.UTF_8));
        response.getHeaders().put("content-type", Collections.singletonList("application/json;charset=utf-8"));
        return response.writeWith(Flux.just(buffer));
    }
}
